package org.pan.service.impl;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.*;
import org.pan.domain.PageResult;
import org.pan.domain.db.CardUser;
import org.pan.domain.db.PhysicalCard;
import org.pan.service.CardUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service("cardUserService")
public class CardUserServiceImpl extends AbstractService implements CardUserService {

    @Transactional
    @Override
    public Long saveCardUser(CardUser cardUser){
        getHibernateTemplate().saveOrUpdate(cardUser);
        return cardUser.getId();
    }

    @Override
    public CardUser getCardUserById(Long id){
        return getHibernateTemplate().get(CardUser.class,id);
    }

    @Override
    public PhysicalCard getPhysicalCardById(Long id){
        return getHibernateTemplate().get(PhysicalCard.class,id);
    }

    @Transactional
    @Override
    public Long savePhysicalCard(PhysicalCard physicalCard){
        getHibernateTemplate().saveOrUpdate(physicalCard);

        CardUser cardUser = physicalCard.getCardUser();
        if (cardUser != null && cardUser.getId() != null){
            CardUser user = getHibernateTemplate().get(CardUser.class, cardUser.getId());
            getHibernateTemplate().update(user);
        }
        return physicalCard.getId();
    }

    @Override
    public List<CardUser> getCardUserList(int first, int max, CardUser cardUser){
        DetachedCriteria detachedCriteria = createCardUserListCriteria(cardUser);
        detachedCriteria.addOrder(Order.desc(CardUser.Property.identifier.name()));
        return (List<CardUser>) getHibernateTemplate().findByCriteria(detachedCriteria,first,max);
    }

    @Override
    public PageResult createPageResult(Integer page, Integer pageSize, CardUser cardUser) {
        DetachedCriteria cardUserListCriteria = createCardUserListCriteria(cardUser);
        cardUserListCriteria.addOrder(Order.desc(CardUser.Property.identifier.name()));

        DetachedCriteria countListCriteria = createCardUserListCriteria(cardUser);

        return createPageResult(page,pageSize,cardUserListCriteria,countListCriteria);
    }

    @Override
    public int countCardUserList(CardUser cardUser) {
        DetachedCriteria cardUserListCriteria = createCardUserListCriteria(cardUser);
        Long size = (Long)getHibernateTemplate().findByCriteria(cardUserListCriteria).get(0);
        return size.intValue();
    }

    private DetachedCriteria createCardUserListCriteria(CardUser cardUser){
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(CardUser.class, "cardUser");

        if (cardUser == null) {
            return detachedCriteria;
        }

        if (StringUtils.isNotEmpty(cardUser.getIdentifier())){
            detachedCriteria.add(Restrictions.like(CardUser.Property.identifier.name(),cardUser.getIdentifier(), MatchMode.ANYWHERE));
        }

        if (StringUtils.isNotEmpty(cardUser.getIDCard())){
            detachedCriteria.add(Restrictions.like(CardUser.Property.IDCard.name(),cardUser.getIDCard(), MatchMode.ANYWHERE));
        }

        if (StringUtils.isNotEmpty(cardUser.getName())){
            detachedCriteria.add(Restrictions.like(CardUser.Property.name.name(),cardUser.getName(), MatchMode.ANYWHERE));
        }

        if (StringUtils.isNotEmpty(cardUser.getEmail())){
            detachedCriteria.add(Restrictions.like(CardUser.Property.email.name(),cardUser.getEmail(), MatchMode.ANYWHERE));
        }

        PhysicalCard physicalCard = cardUser.getPhysicalCard();

        if (physicalCard == null) {
            return detachedCriteria;
        }

        if (StringUtils.isNotEmpty(physicalCard.getIdentifier())){
            detachedCriteria.add(Restrictions.like(CardUser.Property.cardIdentifierJoinStr.name(),physicalCard.getIdentifier(),MatchMode.ANYWHERE));
        }

        if (StringUtils.isNotEmpty(physicalCard.getIdentifier())){
            detachedCriteria.add(Restrictions.like(CardUser.Property.cardSerialNumberJoinStr.name(),physicalCard.getSerialNumber(),MatchMode.ANYWHERE));
        }

        if (physicalCard.getStatus() != null){
            detachedCriteria.add(Restrictions.eq(CardUser.Property.cardUserState.name(),physicalCard.getSerialNumber()));
        }

        return detachedCriteria;
    }

}
